package connectionService;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;

import android.os.StrictMode;
import android.util.Log;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.SoapFault;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.ksoap2.serialization.PropertyInfo;
import org.xmlpull.v1.XmlPullParserException;

import entities.Device;
import entities.DeviceType;
import entities.User;


public class ConnectionServiceAndroidClient implements Serializable{
	public static String getURL() {
		return URL;
	}
	public static void setURL(String uRL) {
		URL = uRL;
	}
	public static String getNamespace() {
		return NAMESPACE;
	}

	private static final String NAMESPACE = "http://awConnectionService/";
	private static String URL="http://192.168.2.117:2082/cs?WSDL"; 
	
	public ConnectionServiceAndroidClient(){
		StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
		StrictMode.setThreadPolicy(policy);
	}
	//Add, Update, Remove Device
	public void makeCall(String method, String UUID, String name, String ip, String type, ArrayList<String> connections){
		SoapObject request = new SoapObject(NAMESPACE, method);

		PropertyInfo propUUID = new PropertyInfo();
		propUUID.setName("arg0");
		propUUID.setValue(UUID);
		propUUID.setType(String.class);
		request.addProperty(propUUID);
		
		PropertyInfo propName = new PropertyInfo();
		propName.setName("arg1");
		propName.setValue(name);
		propName.setType(String.class);
		request.addProperty(propName);
		
		PropertyInfo propIp = new PropertyInfo();
		propIp.setName("arg2");
		propIp.setValue(ip);
		propIp.setType(String.class);
		request.addProperty(propIp);
		
		PropertyInfo propType = new PropertyInfo();
		propType.setName("arg3");
		propType.setValue(type);
		propType.setType(String.class);
		request.addProperty(propType);
		
		PropertyInfo propConnections = new PropertyInfo();
		propConnections.setName("arg4");
		propConnections.setValue(connections);
		propConnections.setType(ArrayList.class);
		request.addProperty(propConnections);
				//
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
		envelope.setOutputSoapObject(request);
		HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
		
		try {
			androidHttpTransport.call(NAMESPACE+method, envelope);
		} catch (IOException e) {e.printStackTrace();
		} catch (XmlPullParserException e) {e.printStackTrace();
		}
	}
	//GetDeviceByUUID, GetDeviceByIp
	public Device getDevice(String ipuuid, boolean ip){
		//IP true == getDeviceByIp :: false == getDeviceByUUID
		String method = "getDeviceByUUID";
		if(ip)
			method = "getDeviceByIp";
		
		SoapObject request = new SoapObject(NAMESPACE, method);
		PropertyInfo propInfo = new PropertyInfo();
		propInfo.setName("arg0");
		propInfo.setValue(ipuuid);
		propInfo.setType(String.class);
		request.addProperty(propInfo);
		
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
		envelope.setOutputSoapObject(request);
		HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
		
		try {
			androidHttpTransport.call(NAMESPACE+method, envelope);
		} catch (IOException e) {e.printStackTrace(); 
		} catch (XmlPullParserException e) {e.printStackTrace(); 
		}
		
		
		Device d = new Device();
		d.setDeviceName("NOTFOUND");
		
		//
		try {
			SoapObject so = (SoapObject) envelope.getResponse();
			
			ArrayList<String> connections = new ArrayList<String>();
			if(so != null){
				Log.i("CSAC:", so.toString());
				int childCount = so.getPropertyCount();
				if(childCount > 4){
					
					for(int i = 0; i < childCount-4; i++){
						connections.add(so.getProperty(i).toString());				
					}
					
					d.setDeviceName(so.getProperty("deviceName").toString());
					d.setDeviceType(DeviceType.valueOf(so.getProperty("deviceType").toString()));
					d.setIpAddress(so.getProperty("ipAddress").toString());
					d.setUUID(so.getProperty("UUID").toString());
					d.setConnectedDevices(connections);
				}else if(childCount == 4){
					d.setDeviceName(so.getProperty("deviceName").toString());
					d.setDeviceType(DeviceType.valueOf(so.getProperty("deviceType").toString()));
					d.setIpAddress(so.getProperty("ipAddress").toString());
					d.setUUID(so.getProperty("UUID").toString());
					d.setConnectedDevices(connections);
				}	
			}
		} catch (SoapFault e) {e.printStackTrace(); System.out.println("SOAPFAULT");
		}
		
		return d;
	}
	//ConnectDevices
	public void connectDevices(String hostUUID, String targetIp, String pairKey){
		System.out.println("CONNECT DEVICES ANDROID CLIENT");
		String method = "connectDevices";
		SoapObject request = new SoapObject(NAMESPACE, method);
		System.out.println(hostUUID);
		System.out.println(targetIp);
		PropertyInfo propInfoMac = new PropertyInfo();
		propInfoMac.setName("arg0");
		propInfoMac.setValue(hostUUID);
		propInfoMac.setType(String.class);
		//jhdfddfdfdfd
		PropertyInfo propInfoIp = new PropertyInfo();
		propInfoIp.setName("arg1");
		propInfoIp.setValue(targetIp);
		propInfoIp.setType(String.class);
		
		PropertyInfo propInfoKey = new PropertyInfo();
		propInfoKey.setName("arg2");
		propInfoKey.setValue(pairKey);
		propInfoKey.setType(String.class);
		
		request.addProperty(propInfoMac);
		request.addProperty(propInfoIp);
		request.addProperty(propInfoKey);
		
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
		envelope.setOutputSoapObject(request);
		HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
		
		try {
			androidHttpTransport.call(NAMESPACE+method, envelope);
		} catch (IOException e) {e.printStackTrace();
		} catch (XmlPullParserException e) {e.printStackTrace();
		}
	}
	
	//getUser
	public User getUser(String username){
		String method = "getUser";
		SoapObject request = new SoapObject(NAMESPACE, method);
		
		PropertyInfo propInfoUsername = new PropertyInfo();
		propInfoUsername.setName("arg0");
		propInfoUsername.setValue(username);
		propInfoUsername.setType(String.class);
		
		request.addProperty(propInfoUsername);
		
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
		envelope.setOutputSoapObject(request);
		HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
		
		try{
			androidHttpTransport.call(NAMESPACE+method, envelope);
		} catch (IOException e){e.printStackTrace();
		} catch (XmlPullParserException e){e.printStackTrace();
		}
		
		User u = new User();
		u.setUsername("NOTFOUND");
		
		try {
			System.out.println(envelope);
			SoapObject so = (SoapObject) envelope.getResponse();
			System.out.println(so);
			
			if(so != null){
				int propertiesSize = so.getPropertyCount();
				if(propertiesSize > 1){
					u.setId(so.getProperty("id").toString());
					u.setUsername(so.getProperty("username").toString());
					u.setFname(so.getProperty("fname").toString());
					u.setLname(so.getProperty("lname").toString());
					u.setEmail(so.getProperty("email").toString());
					u.setPassword(so.getProperty("password").toString());
					u.setRole(so.getProperty("role").toString());
				}else if(propertiesSize > 0){
					u.setUsername(so.getProperty("username").toString());
				}else{
					u.setUsername("NOTFOUND");
				}
			}
			
		} catch (SoapFault e) {e.printStackTrace();
		}
		
		return u;
	}
	
	public void addUser(User u){
		String method = "addUser";
		SoapObject request = new SoapObject(NAMESPACE, method);
		
		PropertyInfo propInfoUsername = new PropertyInfo();
		propInfoUsername.setName("arg0");
		propInfoUsername.setValue(u.getUsername());
		propInfoUsername.setType(String.class);
		request.addProperty(propInfoUsername);
		
		PropertyInfo propInfoPassword = new PropertyInfo();
		propInfoUsername.setName("arg1");
		propInfoUsername.setValue(u.getPassword());
		propInfoUsername.setType(String.class);
		request.addProperty(propInfoPassword);
		
		PropertyInfo propInfoFname = new PropertyInfo();
		propInfoUsername.setName("arg2");
		propInfoUsername.setValue(u.getFname());
		propInfoUsername.setType(String.class);
		request.addProperty(propInfoFname);
		
		PropertyInfo propInfoLname = new PropertyInfo();
		propInfoUsername.setName("arg3");
		propInfoUsername.setValue(u.getLname());
		propInfoUsername.setType(String.class);
		request.addProperty(propInfoLname);
		
		PropertyInfo propInfoEmail = new PropertyInfo();
		propInfoUsername.setName("arg4");
		propInfoUsername.setValue(u.getEmail());
		propInfoUsername.setType(String.class);
		request.addProperty(propInfoEmail);
		
		PropertyInfo propInfoRole = new PropertyInfo();
		propInfoUsername.setName("arg5");
		propInfoUsername.setValue(u.getRole());
		propInfoUsername.setType(String.class);
		request.addProperty(propInfoRole);
		
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
		envelope.setOutputSoapObject(request);
		HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
		
		try{
			System.out.println(NAMESPACE+method);
			androidHttpTransport.call(NAMESPACE+method, envelope);
		} catch (IOException e){e.printStackTrace();
		} catch (XmlPullParserException e){e.printStackTrace();
		}
	}
	
	public void addUserDevice(String uuid, String id){
		System.out.println("ADD USER DEVICE");
		String method = "addUserDevice";
		SoapObject request = new SoapObject(NAMESPACE, method);
		System.out.println("request");
		PropertyInfo propInfoUuid = new PropertyInfo();
		propInfoUuid.setName("arg0");
		propInfoUuid.setValue(uuid);
		propInfoUuid.setType(String.class);
		request.addProperty(propInfoUuid);
		
		PropertyInfo propInfoId = new PropertyInfo();
		propInfoId.setName("arg1");
		propInfoId.setValue(id);
		propInfoId.setType(String.class);
		request.addProperty(propInfoId);
		
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
		envelope.setOutputSoapObject(request);
		HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
		System.out.println("FOUD");
		try{
			System.out.println("BEFORECALL");
			System.out.println(NAMESPACE+method);
			androidHttpTransport.call(NAMESPACE+method, envelope);
			System.out.println("GOOD CALL");
		} catch (IOException e){e.printStackTrace();
		} catch (XmlPullParserException e){e.printStackTrace();
		}
	}
	
	public ArrayList<Device> getDevicesByUser(String id){
		ArrayList<Device> devices = new ArrayList<Device>();
		String method = "getDevicesByUser";
		SoapObject request = new SoapObject(NAMESPACE, method);
		
		PropertyInfo propInfo = new PropertyInfo();
		propInfo.setName("arg0");
		propInfo.setValue(id);
		propInfo.setType(String.class);
		request.addProperty(propInfo);
		
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
		envelope.setOutputSoapObject(request);
		HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
		
		try {
			System.out.println(NAMESPACE+method);
			androidHttpTransport.call(NAMESPACE+method, envelope);
			System.out.println("CSAC After calls");
		} catch (IOException e) {e.printStackTrace(); 
		} catch (XmlPullParserException e) {e.printStackTrace(); 
		}
		System.out.println("MARLUK");
		
		try {
			SoapObject so = (SoapObject) envelope.getResponse();
			
			if(so != null){//
				int childCount = so.getPropertyCount();
				if(childCount > 4){
					
	//				for(int i = 0; i < childCount-4; i++){
	//					devices.add(so.getProperty(i).toString());				
	//				}
	//				
	//				d.setDeviceName(so.getProperty("deviceName").toString());
	//				d.setDeviceType(DeviceType.valueOf(so.getProperty("deviceType").toString()));
	//				d.setIpAddress(so.getProperty("ipAddress").toString());
	//				d.setUUID(so.getProperty("UUID").toString());
	//				d.setConnectedDevices(connections);
				}else if(childCount == 4){
	//				d.setDeviceName(so.getProperty("deviceName").toString());
	//				d.setDeviceType(DeviceType.valueOf(so.getProperty("deviceType").toString()));
	//				d.setIpAddress(so.getProperty("ipAddress").toString());
	//				d.setUUID(so.getProperty("UUID").toString());
	//				d.setConnectedDevices(connections);
				}
			}
		
		} catch (SoapFault e) {e.printStackTrace();
		}
		return devices;
	}
	
	
	public void insertDevicePair(String uuid, String pairKey){
		Log.i("ConnectionServiceAndroidClient", "insertDevicePair()");
		String method = "insertDevicePair";
		SoapObject request = new SoapObject(NAMESPACE, method);
		
		PropertyInfo propUuid = new PropertyInfo();
		propUuid.setName("arg0");
		propUuid.setValue(uuid);
		propUuid.setType(String.class);
		
		PropertyInfo propKey = new PropertyInfo();
		propKey.setName("arg1");
		propKey.setValue(pairKey);
		propKey.setType(String.class);
		
		request.addProperty(propUuid);
		request.addProperty(propKey);
		
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
		envelope.setOutputSoapObject(request);
		HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
		
		try{
			androidHttpTransport.call(NAMESPACE+method, envelope);
		}catch(IOException ex){ex.printStackTrace();
		}catch(XmlPullParserException ex){ex.printStackTrace();
		}
	}
	public void removeDevicePair(String uuid){
		Log.i("ConnectionServiceAndroidClient", "removeDevicePair()");
		String method = "removeDevicePair";
		SoapObject request = new SoapObject(NAMESPACE, method);
		
		PropertyInfo propUuid = new PropertyInfo();
		propUuid.setName("arg0");
		propUuid.setValue(uuid);
		propUuid.setType(String.class);
		
		request.addProperty(propUuid);
		
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
		envelope.setOutputSoapObject(request);
		HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
		
		try{
			androidHttpTransport.call(NAMESPACE+method, envelope);
		}catch(IOException ex){ex.printStackTrace();
		}catch(XmlPullParserException ex){ex.printStackTrace();
		}
	}
	public void updateDevicePair(String uuid, String pairKey){
		Log.i("ConnectionServiceAndroidClient", "updateDevicePair()");
		String method = "updateDevicePair";
		SoapObject request = new SoapObject(NAMESPACE, method);
		
		PropertyInfo propUuid = new PropertyInfo();
		propUuid.setName("arg0");
		propUuid.setValue(uuid);
		propUuid.setType(String.class);
		
		PropertyInfo propKey = new PropertyInfo();
		propKey.setName("arg1");
		propKey.setValue(pairKey);
		propKey.setType(String.class);
		
		request.addProperty(propUuid);
		request.addProperty(propKey);
		
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
		envelope.setOutputSoapObject(request);
		HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
		
		try{
			androidHttpTransport.call(NAMESPACE+method, envelope);
		}catch(IOException ex){ex.printStackTrace();
		}catch(XmlPullParserException ex){ex.printStackTrace();
		}
	}
	public String getDevicePair(String uuid){
		Log.i("ConnectionServiceAndroidClient", "getDevicePair()");
		String method = "getDevicePair";
		SoapObject request = new SoapObject(NAMESPACE, method);
		
		PropertyInfo propUuid = new PropertyInfo();
		propUuid.setName("arg0");
		propUuid.setValue(uuid);
		propUuid.setType(String.class);
		
		request.addProperty(propUuid);
		
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
		envelope.setOutputSoapObject(request);
		HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
		
		try{
			androidHttpTransport.call(NAMESPACE+method, envelope);
		}catch(IOException ex){ex.printStackTrace();
		}catch(XmlPullParserException ex){ex.printStackTrace();
		}
		
		String pairKey = "";
		//
		try {
			SoapPrimitive so = (SoapPrimitive) envelope.getResponse();
			pairKey = so.toString();
		} catch (SoapFault e) {e.printStackTrace();
		}
		//
		
		
		return pairKey;
	}
}
